
#ifndef __ai_rtsH__
#define __ai_rtsH__

#include "ai_pathfinding.h"
#include "world.h"

namespace WtfEngine {
	/**
	 * Actors must implement this interface in order to have the RtsUnit
	 * AI models applied to them.
	 **/
	class IRtsUnit: public virtual IActor {
		GC_INTERFACE(IRtsUnit);

		public:
			/// Returns a value indicating how the specified unit is affiliated
			/// with this unit. Stronger negative values indicate enemity, positive
			/// indicates friendship.
			virtual tScalar getUnitAffiliation(const tRef& rUnit) const = 0;

			virtual tScalar getHealth() const = 0;
			virtual tScalar getMaxHealth() const = 0;

			/// The unit is looking for enemies within this radius
			virtual tScalar getGuardRadius() const = 0;
			
			/// If the unit is attacking, this is the unit to attack. If the
			/// unit is docking, this is the destination unit.
			virtual tRef	getTargetedUnit() const = 0;

			virtual bool	isSelectable(bool bGroupSelection) const = 0;

			/// Called by attack/guard states, to fire upon a unit.
			/// @returns True if a shot was made.
			virtual bool	AttackUnit(const tRef& rUnit) = 0;


			// Orders are issued by the controlling AI (and players..)

			/// Stops the unit (sets to idle)
			virtual bool StopOrder() = 0;
			/// Called when the unit is requested to move
			virtual bool MoveOrder(const tPosition& vPos) = 0;
			/// Called when the unit is requested to attack a specific unit
			virtual bool AttackOrder(const tRef& rUnit) = 0;
	};

	/**
	 * This interface incorporates mobility (i.e. goal positions), to allow
	 * motion.
	 **/
	class IMobileRtsUnit: public virtual IRtsUnit, public virtual IMobileActor {

	};


	namespace AiModels {
		/**
		 * This namespace encapsulates functionality of RTS units, including
		 * idle/guard states, movement, attacking and retaliation.
		 **/
		namespace RtsUnit {
			using namespace Behaviours;

			class Idle: public AiModel {
			public:
				Idle(): AiModel("ai_rtsunit_idle") {};

				virtual bool Evaluate(const IActor::tRef& rActor);
			};

			class Guard: public AiModel {
			public:
				virtual bool Evaluate(const IActor::tRef& rActor);
			};

			class IntermediateMove: public AiModel {
				protected:
					/// This behaviour takes the desired velocity and uses it
					/// to control the actor directly.
					MotionControl::tRef	mrMotionControl;

					/// This behaviour takes the intermediate goal position
					/// and produces a desired velocity to reach it.
					GoalMotion::tRef	mrGoalMotion;

				public:
					IntermediateMove(const StringPool::Entry& sName, const MotionControl::tRef& rMotionControl, const GoalMotion::tRef& rGoalMotion):
					AiModel(sName), mrMotionControl(rMotionControl), mrGoalMotion(rGoalMotion) {
						
					};

					virtual bool Evaluate(const IActor::tRef& rActor);
					virtual bool Evaluate(const IMobileActor::tRef& rActor, const tPosition& vGoal);
			};

			/**
			 * The unit is moving to a specific goal position.
			 **/
			class Move: public IntermediateMove {
			protected:
				/// Calculates intermediate goals
				Pathfinding::tRef	mrPathfinding;

			public:
				virtual bool Evaluate(const IActor::tRef& rActor);
			};


			/**
			 * The unit is targeting another for attack. This is an AiModel decorator, meaning
			 * that it takes another AiModel as a parameter and executes it after running the
			 * attack logic.
			 **/
			class Attack: public Decorator {
			public:
				Attack(const StringPool::Entry& sName, const AiModel::tRef& rBaseAiModel);

				virtual bool Evaluate(const IActor::tRef& rActor);
			};
		};
	};
};

#endif
